
#include "TFModelImpl.h"
#include "TFConstants.h"
#include <time.h>

TFModelImpl::TFModelImpl()
{
	_menuModel = new TFMenu();
	InitializeAll();
}

TFModelImpl::~TFModelImpl()
{
	if(_menuModel) delete _menuModel; _menuModel = NULL;
	if(board) delete board; board = NULL;
}

void TFModelImpl::InitializeAll()
{
	board = new TFBoard(this);
	playerTurn = BLUE_PLAYER;
	turnState = NEW_GAME;
	isSelected = NOT_SELECTED;
	actionPoints = 0;
	move = new TFGameMove();
	turn = new TFGameTurn();
	initSetup = true;
	canAddTroopRed = false;
	canAddTroopBlue= false;
	numTroops = 0;
	numFlags = 0;
	numBarricades = 0;
}

TF_GAME_MODE TFModelImpl::GetGameMode()
{
	return gameMode;
}

void TFModelImpl::SetGameMode(TF_GAME_MODE newMode)
{
	gameMode = newMode;
}

void TFModelImpl::GetMenuModel(TFMenu *& oMenuModel)
{
	oMenuModel = _menuModel;
}

void TFModelImpl::RandomSetup(TF_PLAYERS player)
{
	int x = 0;
	int y = 0;

	//clear board
	board->ResetBoard(player);
	//I know this is inefficient but I didn't want to break it --Priyesh
	if (player == RED_PLAYER)
	{
		
		//Place red troops and flags.
		for(int i=0;i<3;i++){
			x = abs(((int)time(0)*rand()%8));
			y = 0;

				if(board->GetPieceAt(x, y)->GetPiece() == EMPTY && board->GetPieceAt(x, y+1)->GetPiece() == EMPTY){
					board->AddPiece(x, y, FLAG, player); 
					board->AddPiece(x, y + 1, TROOP_TEMP, player);
				}else{
					i--;
				}

			}

		//Place red barricades.
		for(int i=0;i<6;i++){
			x = abs(((int)time(0)*rand()%8));
			y = abs(((int)time(0)*rand()%4));

			if(board->GetPieceAt(x, y)->GetPiece() == EMPTY ){
				board->AddPiece(x, y, BARRICADE, player); 
			}else{
				i--;
			}
		}
	}
	else
	{
		for(int i=0;i<3;i++){
				x = abs(((int)time(0)*rand()%8));
				y = 7;
				
				if(board->GetPieceAt(x, y)->GetPiece() == EMPTY && board->GetPieceAt(x, y-1)->GetPiece() == EMPTY){
					board->AddPiece(x, y, FLAG, player); 
					board->AddPiece(x, y-1, TROOP_TEMP, player);
				}else{
					i--;
				}

			}

		for(int i=0;i<6;i++){
			x = abs(((int)time(0)*rand()%8));
			y = abs((int)time(0)*rand()%4) + 4;

			if(board->GetPieceAt(x, y)->GetPiece() == EMPTY){
				HRESULT HR = board->AddPiece(x, y, BARRICADE, player); 
				
				//if(HR != S_OK){
				//	i--;
				//}
			}else{
				i--;
			}
		}
	}
	//reset number of pieces to place
	pieces_to_place.clear();
	SetNumTroops(0);
	SetNumFlags(0);
	SetNumBarricades(0);
}


void TFModelImpl::RandomPlaceBarricade(TF_PLAYERS player){
	int x =0;
	int y= 0;
	int offset = 0;

	if(player == BLUE_PLAYER){
		offset = 4;
	}else{
		offset = 0;
	}

	for(int i=0;i<1;i++){
			x = abs(((int)time(0)*rand()%8));
			y = abs((int)time(0)*rand()%4) + offset;

			if(board->GetPieceAt(x, y)->GetPiece() == EMPTY){
				board->AddPiece(x, y, BARRICADE, player); 
			}else{
				i--;
			}

		}

}

void TFModelImpl::RandomPlaceFlagBarricade(TF_PLAYERS player){
	int flagFullCount = 0;
	int flagCount = 0;
	int flagCountRed = 0;
	int flagCountBlue = 0;

	
	
	for(int i=0;i<8;i++){
		TF_PIECE_STATE pieceState = board->GetPieceAt(i, 0)->GetPiece();
		if(pieceState == FLAG_0 || pieceState == FLAG_1 || pieceState == FLAG_2){
			flagCountRed++;
		}
	}

	for(int i=0;i<8;i++){
		TF_PIECE_STATE pieceState = board->GetPieceAt(i, 7)->GetPiece();
		if(pieceState == FLAG_0 || pieceState == FLAG_1 || pieceState == FLAG_2){
			flagCountBlue++;
		}
	}

	int x =0;
	int y = 0;

	if(player == BLUE_PLAYER){
		y = 7;
		flagCount = flagCountBlue;
	}else{
		y = 0;
		flagCount = flagCountRed;
	}

	for(int i=0;i<1;i++){
			x = abs(((int)time(0)*rand()%8));

			if(board->GetPieceAt(x, y)->GetPiece() == FLAG_2){
				flagFullCount++;
			}
			
			if((board->GetPieceAt(x, y)->GetPiece() == FLAG_0) || (board->GetPieceAt(x, y)->GetPiece() == FLAG_1) ) {
				board->AddPiece(x, y, FLAG_FORTIFICATION, player); 
				i = 1;
			}else{
				if(flagFullCount != flagCount){
					i--;
				}
			}

		}

}


int TFModelImpl::PiecesToPlace(){
	return (int)pieces_to_place.size();
}
void TFModelImpl::AddPieceToPlace(TFGamePiece* piece){
	pieces_to_place.push_back(piece);
}

void TFModelImpl::NewGame(){
	
	//Add flags.
	for(int i=0;i<3;i++){
		//Constructor protoype: TF_PIECE_STATE piece, TF_PLAYERS color,	int points
		pieces_to_place.push_back(new TFGamePiece(FLAG_0,BLUE_PLAYER, 0));
		SetNumFlags(GetNumFlags() + 1);
	}

	//Add Troops.
	for(int i=0;i<3;i++){
		pieces_to_place.push_back(new TFGamePiece(TROOP_PIECE,BLUE_PLAYER, 3));
		SetNumTroops(GetNumTroops() + 1);
	}

	//Add baricades.
	for(int i=0;i<6;i++){		
		pieces_to_place.push_back(new TFGamePiece(BARRICADE_1,BLUE_PLAYER, 0));
		SetNumBarricades(GetNumBarricades() + 1);
	}
}


bool TFModelImpl::CanPlacePiece(TF_PIECE_STATE piece){
	for(int i=0;i<(int)pieces_to_place.size();i++){
		if(pieces_to_place.at(i)->GetPiece() == piece){
			return true;
		}
	}
	
	return false;
}

void TFModelImpl::PiecePlaced(TF_PIECE_STATE piece){
	for(int i=0;i<(int)pieces_to_place.size();i++){
		if(pieces_to_place.at(i)->GetPiece() == piece){
			 pieces_to_place.erase(i+pieces_to_place.begin());
			return;
		}
	}
}

HRESULT TFModelImpl::RoomForBarricade()
{
	if (GetTurn() == RED_PLAYER)
	{
		//check row 0 to 3
		for (int j=0; j < 4; j++)
		{
			for(int i=0;i<8;i++)
			{
				TF_PIECE_STATE pieceState = board->GetPieceAt(i, j)->GetPiece();
				if(pieceState == EMPTY)
				{
					return S_OK;
				}
			}
		}
	}
	else
	{
		//check row 4 to 7
		for (int j=4; j < 8; j++)
		{
			for(int i=0;i<8;i++)
			{
				TF_PIECE_STATE pieceState = board->GetPieceAt(i, j)->GetPiece();
				if(pieceState == EMPTY)
				{
					return S_OK;
				}
			}
		}
	}
	return E_FAIL;
}

HRESULT TFModelImpl::CanFortifyFlag()
{
	if (GetTurn() == RED_PLAYER)
	{
		for(int i=0;i<8;i++)
		{
			TF_PIECE_STATE pieceState = board->GetPieceAt(i, 0)->GetPiece();
			if(pieceState == FLAG_0 || pieceState == FLAG_1)
			{
				return S_OK;
			}
		}
	}
	else
	{
		for(int i=0;i<8;i++)
		{
			TF_PIECE_STATE pieceState = board->GetPieceAt(i, 7)->GetPiece();
			if(pieceState == FLAG_0 || pieceState == FLAG_1)
			{
				return S_OK;
			}
		}
	}
	return E_FAIL;
}

HRESULT TFModelImpl::RoomForTroop()
{
	if (GetTurn() == RED_PLAYER)
	{
		//check row 0 and 1
		for (int j=0; j <= 1; j++)
		{
			for(int i=0;i<8;i++)
			{
				TF_PIECE_STATE pieceState = board->GetPieceAt(i, j)->GetPiece();
				if(pieceState == EMPTY)
				{
					return S_OK;
				}
			}
		}
	}
	else
	{
		//check row 6 and 7
		for (int j=6; j <= 7; j++)
		{
			for(int i=0;i<8;i++)
			{
				TF_PIECE_STATE pieceState = board->GetPieceAt(i, j)->GetPiece();
				if(pieceState == EMPTY)
				{
					return S_OK;
				}
			}
		}
	}
	return E_FAIL;
}
